package com.example.demo.util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.example.demo.config.ConstantConfig;
import com.example.demo.enums.StatusCodeEnum;
import com.example.demo.exception.CustomException;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Date;

/**
 * @description：操作本服务文件的工具类.
 * @author：lw
 * @create_time：2024/1/22
 **/
public class LocalFileUtil {

    private static  final String  uploadFileFolder ="/files/";

    public static String getFileNameByFullFileUrl(String fullFileUrl){
        return fullFileUrl.split(ConstantConfig.serverUrl+uploadFileFolder)[1];
    }

    private static String getStaticPath(ResourceLoader resourceLoader) {
        // 获取 'static' 目录对应的资源对象,在获取之前，需要存在static目录，且该目录下要有资源
        Resource resource =resourceLoader.getResource("classpath:/static");
        try {
            // 获取资源的URL，并转换为路径字符串。resource.getURI().getPath() -> /D:/java_projects/mp_study/target/classes/static。
            // 咋们文件上传到本地得传到编译文件夹里，否则不生效
            return resource.getURI().getPath();
        }
        catch (IOException e) {
            // 处理无法获取资源路径的情况
            throw new RuntimeException(e.getMessage());
        }
    }

    public static String upload(MultipartFile file, String fileType, ResourceLoader resourceLoader) {   // 多文件上传则循环调用该方法即可
        try {
            String folderPath=uploadFileFolder  + DateUtil.format(new Date(), "yyyyMMdd") + "/" + fileType;
            String folderPath_absolute=getStaticPath(resourceLoader) + folderPath;
            // 判断文件夹是否存在，不存在时，创建文件夹
            File directoryFile = new File(folderPath_absolute);
            if (!directoryFile.exists()) { // 创建多个文件夹
                if(!directoryFile.mkdirs()) throw new  RuntimeException("文件夹创建失败！");
            }
            // 判断文件是否为空，不为空时，保存文件
            if (!file.isEmpty()) {
                String filename =IdUtil.simpleUUID() + ConstantConfig.fileNameSplitSymbol + file.getOriginalFilename();
                file.transferTo(new File(folderPath_absolute, filename));
                return ConstantConfig.serverUrl+ folderPath + "/" + filename;         // 路径规则与minio的上传一样
            }else throw new CustomException(StatusCodeEnum.file_null);
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomException(StatusCodeEnum.upload_fail);
        }
    }

    public static void download(String fileName, HttpServletResponse response,ResourceLoader resourceLoader) {

        if (StrUtil.isBlank(fileName))   throw  new CustomException(StatusCodeEnum.fileName_null);
        String filePath=getStaticPath(resourceLoader) + uploadFileFolder + fileName;
        FileSystemResource file = new FileSystemResource(filePath);
        try(
                InputStream inputStream = file.getInputStream();
                OutputStream outputStream = response.getOutputStream();
        )
        {
            String really_fileName=URLEncoder.encode(fileName.split(ConstantConfig.fileNameSplitSymbol)[1], StandardCharsets.UTF_8);
            response.setHeader("Content-Disposition", "attachment;filename=" +really_fileName);
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding("UTF-8");
            byte[] buf = new byte[1024];
            int length = 0;
            while ((length = inputStream.read(buf)) > 0) {
                outputStream.write(buf, 0, length);
            }
        } catch (Throwable e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    public static ResponseEntity<InputStreamResource> download(String fileName, ResourceLoader resourceLoader) throws IOException {

        if (StrUtil.isBlank(fileName))   throw  new CustomException(StatusCodeEnum.fileName_null);

        // 读取文件
        String filePath=getStaticPath(resourceLoader) + uploadFileFolder + fileName;
        FileSystemResource file = new FileSystemResource(filePath);

        String really_fileName= URLEncoder.encode(fileName.split(ConstantConfig.fileNameSplitSymbol)[1], StandardCharsets.UTF_8);
        // 设置响应头
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Disposition", "attachment;filename=" +really_fileName);
        return ResponseEntity
                .ok()
                .headers(headers)
                .contentLength(file.contentLength())
                .contentType(MediaType.parseMediaType("application/octet-stream"))
                .body(new InputStreamResource(file.getInputStream()));
    }

    public static  boolean delete(String fileName,ResourceLoader resourceLoader){
        return  new File(getStaticPath(resourceLoader)+uploadFileFolder ,fileName).delete();
    }
}
